package com.xyzk.diagnose.activity.bluetooth;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.UUID;
//
//import com.xyzk.diagnose.activity.bluetoothGatt.BleBluetoothManager;
//import com.xyzk.diagnose.activity.bluetoothGatt.BleGattCallback;
//import com.xyzk.diagnose.activity.bluetoothGatt.GattTools.AidApplication;
//import com.xyzk.diagnose.activity.bluetoothGatt.GattTools.LogUtil;
import com.xyzk.diagnose.entity.Can;
import com.xyzk.diagnose.entity.Cartype;
import com.xyzk.diagnose.tools.Common;
import com.xyzk.diagnose.tools.Commonfunc;
import com.xyzk.diagnose.tools.LogFile;

import android.annotation.SuppressLint;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.util.Log;

public class BluetoothService{
	private static final String TAG = "BluetoothService";
	private final UUID mUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
	private static  BluetoothService mService;
	private BluetoothAdapter mAdapter;
	private BluetoothDevice mDevice;
	private BluetoothSocket mSocket;
	private InputStream mInputSteam;
	private OutputStream mOutputStream;
	private Handler mHandler;
//	private BleBluetoothManager bleBluetoothManager;
	private int mState;
	private Cartype cartype = Cartype.getInstance();
	public LogFile mLog = LogFile.getInstance();
	public boolean exit;
	private Context context;

	private BluetoothService(){
		mAdapter = BluetoothAdapter.getDefaultAdapter();
	}

	public synchronized static BluetoothService getInstance(){
		return mService == null ? mService = new BluetoothService() : mService;
	}

	/**
	 * 赋值handler
	 * @param handler
	 */
	public void setHandler(Handler handler){
		mHandler = handler;
	}

	/**
	 * 记录日志
	 * @param canid 1表示发送 2表示接收 3表示7DF
	 * @param data 日志
	 */
	public void saveLogData(int path,String data){
		if(mLog != null) mLog.printMessage(path,data);
	}
	public void PrintLog(String Pstr)
	{
		if(mLog != null)
		{
			mLog.PrintLog(Pstr);
		}
	}
	public String getFilePaths(){
		return mLog.getFilePath();
	}
	public void OpenLogfile(String Pfile)
	{
		mLog = new LogFile(Pfile, true);
	}
	public long GetLogfileSize()
	{
		return mLog.getFileSize();
	}
	public String GetLogfileName()
	{
		//去掉LOG标志
		int v_adr = mLog.m_filename.indexOf("LOG");
		String v_name = null;
		if(v_adr > 0 && v_adr < 100)
			v_name = mLog.m_filename.substring(v_adr + 4);
		else
		{
			v_name = Commonfunc.getDate("") + "/" + mLog.m_filename;
		}
		return v_name;
	}
	public long readLogfile(char [] Pbuf)
	{
		return mLog.readFile(Pbuf);
	}
	/**
	 * 参数为蓝牙MAC地址,长度为17位 格式为：“00:00:00:00:00:00”
	 * @param macAddr 物理地址
	 */
	public void connectDevice(String macAddr){
		if(isConnecting()) return;
		mDevice = mAdapter.getRemoteDevice(macAddr);
		if(mDevice == null) return;
//		bleBluetoothManager=new BleBluetoothManager(context);
//		bleBluetoothManager.connectBle(mDevice);
		new ConnectThread(macAddr).start();
		setBlueState(Common.BLUE_STATE_CONNECTING);
	}

	public void setContext(Context context) {
		this.context=context;
	}

	/****************************蓝牙连接线程***************************************/
	private class ConnectThread extends Thread{
		private String macAddr;
		public ConnectThread(String macAddr) {
			this.macAddr = macAddr;
		}
		@Override
		public void run() {
			try{
				Log.i(TAG, "连接Socket");
				mSocket = mDevice.createRfcommSocketToServiceRecord(mUUID);
				setName("ConnectThread");
				mAdapter.cancelDiscovery();
				mSocket.connect();
				mInputSteam = mSocket.getInputStream();
				mOutputStream = mSocket.getOutputStream();
			}catch (IOException e){
				Log.i(TAG, "Socket连接失败!");
				setBlueState(Common.BLUE_STATE_CONNECT_FAILD);
				try{
					mSocket.close();
				}catch (IOException e2){
					Log.e(TAG, "unable to close() socket during connection failure", e2);
				}
				mHandler.obtainMessage(Common.BLUE_RECEIVE_CONNECT,0,0).sendToTarget();
				return;
			}
			Log.i(TAG, "Socket连接成功!");
			setBlueState(Common.BLUE_STATE_CONNECTED);
			mHandler.obtainMessage(Common.BLUE_RECEIVE_CONNECT,1,0).sendToTarget();
			Commonfunc.setSharedPreference(Common.MAC_ADDRESS, macAddr);
			return;
		}
	}



	/**
	 * 设置蓝牙状态
	 * @param state 已连接 未连接 连接失败 连接中
	 */
	public void setBlueState(int state){
		mState = state;
	}

	/**
	 * 是否已连接
	 */
	public boolean isConnected(){
		return mState == Common.BLUE_STATE_CONNECTED ? true : false;
	}

	/**
	 * 是否正在连接
	 */
	public boolean isConnecting(){
		return mState == Common.BLUE_STATE_CONNECTING ? true : false;
	}

	/**
	 * 连接失败或者未连接
	 */
	public boolean isConnectLost(){
		return (mState == Common.BLUE_STATE_NONE || mState == Common.BLUE_STATE_CONNECT_FAILD) ? true : false;
	}

	/**
	 * 关闭蓝牙服务
	 */
	public void stopService(){
		setBlueState(Common.BLUE_STATE_NONE);
		try{
			if(mSocket != null){
				mSocket.close();
				mSocket = null;
			}
			if(mInputSteam != null){
				mInputSteam.close();
				mInputSteam = null;
			}
			if(mOutputStream != null){
				mOutputStream.close();
				mOutputStream = null;
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 开始记录日志
	 * @param vin
	 */
	public void startRecord(String vin){
		mLog.startRecord(vin);
	}

	/****************************蓝牙CAN通信***************************************/
	private int addData2Cmd(byte [] cmd,byte [] Pdata,int Plen,byte [] Pcmdbuf){
		int cmdlen = 0;
		//先添加发送帧头
		Pcmdbuf[0] = 0x55;
		Pcmdbuf[1] = (byte) 0xAA;
		Pcmdbuf[2] = (byte) 0xC1;
		Pcmdbuf[3] = (byte) 0xB1;
		cmdlen = 4 + 2 + 2 + Plen + 1;//计算长度
		//填入长度字节
		Pcmdbuf[4] = (byte) ((cmdlen - 6) / 0x100);
		Pcmdbuf[5] = (byte) ((cmdlen - 6) % 0x100);
		//填入命令字
		Pcmdbuf[6] = cmd[0];
		Pcmdbuf[7] = cmd[1];
		//填入DATA
		for(int i = 0; i < Plen; i ++){
			Pcmdbuf[8+i] = Pdata[i];
		}
		Pcmdbuf[cmdlen - 1] = Commonfunc.calcuCheckCode(Pcmdbuf,4,cmdlen - 1);
		return cmdlen;
	}

	//发送数据，发一次接收一次
	private int sendOneToOne(byte[] Psend,int Plen,byte[] Precv,int maxtime){
		int len = 0;
		if(mOutputStream == null || mInputSteam == null || exit) return -1; //未连接
		try {
			if(mInputSteam.available() > 0){  //先清除数据
				mInputSteam.read(Precv, 0, mInputSteam.available());
			}
			Commonfunc.sleep(1);
			mOutputStream.write(Psend, 0, Plen);
			Commonfunc.sleep(1);
			mOutputStream.flush();
			Commonfunc.sleep(5);
			//if(Common.DEBUG) Log.i(TAG,"Send:" + Commonfunc.bytesToHexStringSpace(Psend, 0,Plen));
		} catch (IOException e) {
			e.printStackTrace();
			if(Common.DEBUG) Log.e(TAG,"Send异常");
		}
		len = readData(Precv,maxtime);
		return len;
	}

	public int CanSendAndRecvN2N(byte [] Send,int Plen,byte [] Recv,int Psize,int errorcode,int maxtime)
	{
		int error = 0;
		byte [] Readbuf = new byte[256];
		int i,iRet = 0;
		for(i = 0; i < Common.cmd_freq; i ++)
		{
			iRet = CanSendMore2More(Send,Plen,Readbuf,Readbuf.length,maxtime);
			if(iRet > 0) break;
			if(exit) return 5002;
			Commonfunc.sleep(Common.waittime);
		}
		if(i >= Common.cmd_freq) return 5001; //无响应
		if ((Readbuf[1]&0xFF) == ((Send[1] + 0x40)&0xFF)) //判断结果
		{
			error = 0;
		}
		else
		{
			error = errorcode;
		}
		//复制接收数据
		if(iRet > Psize)
			iRet = Psize - 1;
		if(iRet > 0x200 || iRet < 1) return error;
		System.arraycopy(Readbuf, 0, Recv, 0, iRet);
		return error;
	}

	//cmd CAN 发多帧收多帧
	private int CanSendMore2More(byte[] send,int Plen,byte [] recv,int Psize,int maxtime)
	{
		byte [] cmd = new byte[]{0x11,0x31};
		byte [] data = new byte[256];
		//记录发送的数据
		if(mLog != null){
			String result=Commonfunc.Chery_kf_bytesToHexString(send, 0, Plen);
			mLog.PrintAppend(1,result);
		}
		//超时时间
		data[0] = (byte) ((maxtime / 0x100) & 0xFF);
		data[1] = (byte) (maxtime & 0xFF);
		//添加发送命令的帧数以及帧内容
		int framenum = 0;
		if(Plen <= 8) //单帧
		{
			framenum = 1;
			//添加一帧数据
			for (int i = 0; i < Plen; i ++)
			{
				data[3 + i] = send[i];
			}
		}
		else	//多帧
		{
			framenum = (Plen + 6) / 7;
			if (framenum > 25) //越界
			{
				return 0;
			}
			for (int i = 0; i < framenum - 1; i ++)
			{
				//添加帧头
				if (i == 0)
					data[3 +i * 8] = 0x10;
				else
					data[3 +i * 8] = (byte) (0x20 + i % 0x10);
				//添加内容
				for (int j = 0; j < 7; j ++)
				{
					data[3 +i * 8 + 1+j] = send[i * 7 + j];
				}
			}
			//复制最后一帧
			//帧头
			data[3 +(framenum - 1) * 8] = (byte) (((framenum - 1) & 0x0F) + 0x20);
			int lastlen = Plen % 7;
			if(lastlen == 0) lastlen = 7;
			for (int j = 0; j < lastlen; j ++)
			{
				data[3 +(framenum - 1) * 8 + 1+j] = send[(framenum - 1) * 7 + j];
			}
		}
		//获取帧数
		data[2] = (byte)framenum;
		//组合成命令
		byte [] Sendbuf = new byte [256];
		int Sendlen = addData2Cmd(cmd, data, framenum * 8 + 3, Sendbuf);
		if(Common.Debug)
		{
			Log.i(TAG,"Sed:" + Commonfunc.bytesToHexString(send, 0,Plen));
			Log.i(TAG,"Cmd:" + Commonfunc.bytesToHexString(Sendbuf, 0,Sendlen));
		}
		//发送
		byte [] Readbuf = new byte[256];
		//int iRet = SendOneToOne(Sendbuf, Sendlen, Readbuf, Readbuf.length, Common.cmdmaxtime);
		int iRet =SendOneToOneNew(Sendbuf, Sendlen, Readbuf, Readbuf.length, maxtime);
		if(iRet != 9) //nok
		{
			if(iRet >= 0) //
				iRet = -5;
			return iRet;
		}
		//接收数据
		while(true)
		{
			iRet = ReaddataComplete(Readbuf, Readbuf.length, maxtime + 500);
			if(iRet > 9) //ok
			{
				if((Readbuf[5] == 0x0D) && (Readbuf[10] == 0x03) && (Readbuf[11] == 0x7F) && (Readbuf[13] == 0x78)) //wait
				{
					if(mLog != null){
						mLog.PrintAppend(2,Commonfunc.bytesToHexString(Readbuf, 10, 14));
					}
					Commonfunc.sleep(10);
					continue;
				}
				else //拷贝数据
				{
					//拆开CAN包重组CAN数据
					if((Readbuf[8]&0xFF) > 25) break;
					if (Readbuf[8] == 1) //单帧
					{
						iRet = (Readbuf[10]&0xFF) + 1;
						for(int i = 0;i < iRet; i ++)
							recv[i] = Readbuf[10 + i];
					}
					else if (Readbuf[8] > 1) //多帧
					{
						iRet = ((Readbuf[10]&0x0F) << 8) + (Readbuf[11]&0xFF) + 1;
						for(int i = 0; i < Readbuf[8]; i ++)
						{
							System.arraycopy(Readbuf,9 + i * 9 + 2, recv, i * 7, 7);
						}
					}
					break;
				}
			}
			else if(iRet == 9 && Readbuf[6] == 0x6F && Readbuf[7] == 0x02) //timeout
			{
				iRet = -2; break;
			}
			else
				break;
		}
		//记录接收的数据
		if(mLog != null && iRet > 0){
			String result=Commonfunc.Chery_kf_bytesToHexString(recv, 0, iRet);
			mLog.PrintAppend(2,result);
		}
		return iRet;
	}
	//发送数据，发一次收一次
	private int SendOneToOne(byte[] Psend,int Plen,byte[] Precv,int Psize,int maxtime)
	{
		int len = 0;
		if(mOutputStream == null || mInputSteam == null) return -1; //未连接
		try {
			if(mInputSteam.available() > 0)  //先清除数据
				mInputSteam.read(Precv, 0, mInputSteam.available());
			Commonfunc.sleep(1);
			mOutputStream.write(Psend, 0, Plen);
			Commonfunc.sleep(1);
			mOutputStream.flush();
			Commonfunc.sleep(5);
			if(Common.DEBUG) Log.i(TAG,"Send:" + Commonfunc.bytesToHexString(Psend, 0,Plen));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			if(Common.DEBUG) Log.e(TAG,"Send异常");
		}
		len = Readdata(Precv,Psize,maxtime);
		return len;
	}
	//接收数据,保证收到完整帧
	private int readData(byte[] Precv,int maxtime)
	{
		int len = 0;
		int all_len = 0;
		byte [] buf = new byte[256];
		if(mOutputStream == null || mInputSteam == null)
		{
			//if(Common.Debug) Log.e(TAG,"Readdata exit 1");
			return -1; //未连接
		}
		try {
			long starttime = System.currentTimeMillis(); //获得起始时间
			long endtime = starttime;
			while(true)
			{
				Commonfunc.sleep(2);
				if(mInputSteam == null  || exit == true)
				{
					//if(Common.Debug) Log.e(TAG,"Readdata exit 2" + "dout=" + m_out_stream + ";din=" + m_in_stream + ";exit=" + exit);
					len = -2;
					break; //未连接
				}
				len = mInputSteam.available();
				if(len > 0)
				{
					mInputSteam.read(Precv,all_len,len);
					all_len += len;
					//if(Common.Debug) Log.i(TAG,"Read:" + Commonfunc.bytesToHexString(Precv, 0,len));
					if((all_len == 9) && (Precv[5] == 0x03)) //收到下位机回复
					{
						//if(Common.Debug) Log.e(TAG,"Readdata exit 3");
						break;
					}
					else if(all_len > 9) //收到超过一帧,或者长帧
					{
						if(Precv[5] == 0x03) //表示是多帧
						{
							if((all_len - 9) == ((Precv[14] & 0xFF) + 6))
							{
								//if(Common.Debug) Log.e(TAG,"Readdata exit 4");
								break;
							}
						}
						else	//长帧
						{
							if(all_len == ((Precv[5] & 0xFF) + 6))
							{
								//if(Common.Debug) Log.e(TAG,"Readdata exit 5");
								break;
							}
						}
					}
				}
				endtime = System.currentTimeMillis();
				if(endtime  > (starttime + maxtime)) //超时
				{
					//if(Common.Debug) Log.i(TAG,"超时退出!");
					len = -3;
					break;
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			//if(Common.Debug) Log.e(TAG,"接收异常");
		}
		return all_len;
	}

	/**
	 * 发送指定ID一帧报文，不接收数据
	 * @param SendId CANID
	 * @param send 报文指令
	 * @param Plen 指令长度
	 * @return 发送是否成功
	 */
	public int canSendOneOnly(int SendId,byte[] send,int Plen){

		byte [] cmd = new byte[]{0x11,0x39};
		byte [] data = new byte[128];
		if(mLog != null){
			mLog.printMessage(SendId,Commonfunc.bytesToHexString(send, 0, Plen));
		}
		data[0] = 0x01;  //can模式
		data[1] = 0x00;
		data[2] = 0x00;
		data[3] = (byte) (SendId / 0x100);
		data[4] = (byte) (SendId % 0x100);
		//添加发送命令的帧数以及帧内容
		System.arraycopy(send, 0, data, 5, Plen);
		//组合成命令
		byte [] Sendbuf = new byte [128];
		int Sendlen = addData2Cmd(cmd, data, 13, Sendbuf);
		//发送
		byte [] Readbuf = new byte[128];
		int iRet = sendOneToOne(Sendbuf, Sendlen, Readbuf, Common.CMD_MAX_TIME);
		Commonfunc.sleep(Common.SET_WAIT_TIME);
		return iRet == 9 ? 1:0;
	}

	/**
	 * 模块初始化信息
	 * @param moudle 模块
	 * @isFlash 刷写模式的话就随意传个值，否则不传
	 * @return 是否初始化成功
	 */
	public boolean setCanInit(String module, String... isFlash){
		Can can = cartype.getCan(module);//获取CAN对象
		if(can == null) return false;
		int i = 0;
		for(i = 0; i < Common.CMD_REQUEST; i ++){
			if(setCanBaud(can.getBaud())) break;
			Commonfunc.sleep(50);
		}
		if(i >= Common.CMD_REQUEST) return false;

		for(i = 0; i < Common.CMD_REQUEST; i ++){
			if(setCanFilter(can.getAddr(), 2, module)) break;
			Commonfunc.sleep(50);
		}
		if(i >= Common.CMD_REQUEST) return false;

		for(i = 0; i < Common.CMD_REQUEST; i ++){
			if(setCanMode(can.getMode())) break;
			Commonfunc.sleep(50);
		}
		if(i >= Common.CMD_REQUEST) return false;

		for(i = 0; i < Common.CMD_REQUEST; i ++){
			if(isFlash.length > 0){//刷写模式
				if(setCommunTimer(2, 2000, 3000, 1)) break;
			}else{//正常诊断模式
				if(setCommunTimer(5, 2000, 3000, 20)) break;
			}
			Commonfunc.sleep(50);
		}
		if(i >= Common.CMD_REQUEST) return false;

		byte [] canbuf={0x30,0x00,0x0A,0x00,0x00,0x00,0x00,0x00};
		for(i = 0; i < Common.CMD_REQUEST; i ++){
			if(setCanAutoFrame(canbuf, 8)) break;
			Commonfunc.sleep(50);
		}
		if(i >= Common.CMD_REQUEST) return false;
		return true;
	}

	/**
	 * 扩展帧模块初始化信息
	 * @param module 模块名称
	 * @param send 请求ID
	 * @param recv 接收ID
	 * @return 是否初始化成功
	 */
	public boolean setCanInit_Exted(String module,byte [] send, byte[] recv){
		Can can = cartype.getCan(module, "0");//获取CAN对象
		int i = 0;
		byte [] id = can.getAddr();
		System.arraycopy(id, 0, send, 0, 4);//获取请求地址
		System.arraycopy(id, 4, recv, 0, 4);//获取接收地址

		for(i = 0; i < Common.CMD_REQUEST; i ++){
			if(setCanBaud(can.getBaud())) break;
			Commonfunc.sleep(50);
		}
		if(i >= Common.CMD_REQUEST) return false;

		for(i = 0; i < Common.CMD_REQUEST; i ++){
			if(setCanMode(can.getMode())) break;
			Commonfunc.sleep(50);
		}
		if(i >= Common.CMD_REQUEST) return false;

		for(i = 0; i < Common.CMD_REQUEST; i ++){
			if(setCommunTimer(5,2000,3000,10)) break;
			Commonfunc.sleep(50);
		}
		if(i >= Common.CMD_REQUEST) return false;

		byte [] canbuf = {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
		for(i = 0; i < Common.CMD_REQUEST; i ++){
			if(setCanAutoFrame(canbuf, 8)) break;
			Commonfunc.sleep(50);
		}
		if(i >= Common.CMD_REQUEST) return false;
		return true;
	}
	//发送数据，发一次收一次
	private int SendOneToOneNew(byte[] Psend,int Plen,byte[] Precv,int Psize,int maxtime)
	{
		int len = 0;
		if(mOutputStream == null || mInputSteam == null) return -1; //未连接
		try {
			if(mInputSteam.available() > 0)  //先清除数据
				mInputSteam.skip( mInputSteam.available());
			mOutputStream.write(Psend, 0, Plen);
			mOutputStream.flush();
			Commonfunc.sleep(5);
			//if(Common.Debug) Log.i(TAG,"Send:" + Commonfunc.bytesToHexString(Psend, 0,Plen));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			//if(Common.Debug) Log.e(TAG,"Send异常");
		}
		len = ReaddataComplete(Precv,Psize,maxtime);
		return len;
	}
	private int ReaddataComplete(byte[] Precv,int Psize,int maxtime)
	{
		int readlen = 0;
		int all_len = 0;
		int datalen = 0;
		if(mOutputStream == null || mInputSteam == null)
		{
			if(Common.DEBUG) Log.e(TAG,"Readdata exit 1");
			return -1; //断线
		}
		try {
			long starttime = System.currentTimeMillis(); //获得起始时间
			long endtime = starttime;
			while(true)
			{
				Commonfunc.sleep(2);
				if(mOutputStream == null || mInputSteam == null  || exit == true)
				{
					//if(Common.Debug) Log.e(TAG,"Readdata exit 2" + "dout=" + m_out_stream + ";din=" + m_in_stream + ";exit=" + exit);
					break; //未连接
				}
				Commonfunc.sleep(2);
				readlen = mInputSteam.available();
				if((readlen + all_len) >= 9)
				{
					if(datalen == 0) //开始
					{
						mInputSteam.read(Precv,0,6);
						all_len += 6;
						if(((Precv[0]&0xFF) == 0x55) && ((Precv[1]&0xFF) == 0xAA))  //得到头
						{
							datalen = ((Precv[4]&0xFF) << 8) + (Precv[5]&0xFF);
							if(datalen <= (readlen - 6)) //有完整数据,取数据返回
							{
								readlen = mInputSteam.read(Precv,all_len,datalen);
								if(readlen == datalen) //ok返回
								{
									all_len += datalen;
									break;
								}
								else //清空
								{
									all_len = 0;
									datalen = 0;
								}
							}
							else //无完整数据
							{
								if(datalen < 3) //error,或者无效数据
								{
									all_len = 0;
									datalen = 0;
								}
							}
						}
						else //无效数据
						{
							all_len = 0;
							datalen = 0;
						}
					}
					else
					{
						if(readlen >= datalen) //数据全了
						{
							readlen = mInputSteam.read(Precv,all_len,datalen);
							if(readlen == datalen) //ok返回
							{
								all_len += datalen;
								break;
							}
							else //清空
							{
								all_len = 0;
								datalen = 0;
							}
						}
					}
				}
				endtime = System.currentTimeMillis();
				if(endtime  > (starttime + maxtime)) //超时
				{
					if(Common.DEBUG) Log.i(TAG,"超时退出!");
					all_len = -2; //超时
					break;
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
			all_len = -3; //IO异常
			if(Common.DEBUG) Log.e(TAG,"接收异常");
		}
		//计算校验
		if(all_len > 1)
		{
			if(Precv[all_len - 1] != Commonfunc.CalcChechSum(Precv, 4, all_len - 1)) //nok
				all_len = -4; //校验失败
		}
		return all_len;
	}
	//只收数据,保证收到完整帧
	private int Readdata(byte[] Precv,int Psize,int maxtime)
	{
		int len = 0;
		int all_len = 0;
		byte [] buf = new byte[256];
		if(mOutputStream == null || mInputSteam == null)
		{
			if(Common.DEBUG) Log.e(TAG,"Readdata exit 1");
			return -1; //未连接
		}
		try {
			long starttime = System.currentTimeMillis(); //获得起始时间
			long endtime = starttime;
			while(true)
			{
				Commonfunc.sleep(2);
				if(mOutputStream == null || mInputSteam == null  || exit == true)
				{
					if(Common.DEBUG) Log.e(TAG,"Readdata exit 2" + "dout=" + mOutputStream + ";din=" + mInputSteam + ";exit=" + exit);
					break; //未连接
				}
				len = mInputSteam.available();
				if(len > 0)
				{
					mInputSteam.read(Precv,all_len,len);
					all_len += len;
					if(Common.DEBUG) Log.i(TAG,"Read:" + Commonfunc.bytesToHexString(Precv, 0,len));
					if((all_len == 9) && (Precv[5] == 0x03)) //收到下位机回复
					{
						//if(Common.Debug) Log.e(TAG,"Readdata exit 3");
						break;
					}
					else if(all_len > 9) //收到超过一帧,或者长帧
					{
						if(Precv[5] == 0x03) //表示是多帧
						{
							if((all_len - 9) == ((Precv[14] & 0xFF) + 6))
							{
								//if(Common.Debug) Log.e(TAG,"Readdata exit 4");
								break;
							}
						}
						else	//长帧
						{
							if(all_len == ((Precv[5] & 0xFF) + 6))
							{
								//if(Common.Debug) Log.e(TAG,"Readdata exit 5");
								break;
							}
						}
					}
				}
				endtime = System.currentTimeMillis();
				if(endtime  > (starttime + maxtime)) //超时

				{
					if(Common.DEBUG) Log.i(TAG,"超时退出!");
					break;
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			if(Common.DEBUG) Log.e(TAG,"接收异常");
		}
		return len;
	}
	//设置CAN线波特率
	public boolean setCanBaud(long baud){
		byte [] cmd = new byte[]{0x55,(byte) 0xAA,(byte) 0xC1,(byte) 0xB1,0x00,0x06,0x10,0x03,0x00,0x00,0x00,0x00};
		byte [] Ans = new byte[512];
		if(mLog != null) mLog.printMessage(0,"SetBaud:" + baud);
		cmd[8] = (byte) ((baud / 0x10000) & 0xFF);
		cmd[9] = (byte) ((baud / 0x100) & 0xFF);
		cmd[10] = (byte) (baud & 0xFF);
		cmd[11] = Commonfunc.calcuCheckCode(cmd, 4, 11);
		int rlen = sendOneToOne(cmd,cmd.length,Ans,Common.SET_MAX_TIME);
		return rlen > 0 && (Ans[6] == (byte) (cmd[6] + 0x40));
	}
	//设置标准帧中继数据
	public boolean SetStandCanAutoFrame(int Pid,byte [] Pbuf,int Plen)
	{
		byte [] cmd = new byte[]{0x55,(byte) 0xAA,(byte) 0xC1,(byte) 0xB1,0x00,0x0D,0x10,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
		byte [] Ans = new byte[128];
		cmd[8] = (byte) (Pid / 0x100);
		cmd[9] = (byte) (Pid &0xFF);
		for(int i = 0; i < Plen; i ++)
		{
			cmd[10 + i] = Pbuf[i];
		}
		//计算校验
		cmd[10 + Plen] = Commonfunc.calcuCheckCode(cmd, 4, 10 + Plen);
		int rlen = sendOneToOne(cmd, cmd.length, Ans, Common.SET_MAX_TIME);
		if(rlen > 0 && (Ans[6] == (byte) (cmd[6] + 0x40)))
		{
			if(mLog != null) mLog.printMessage(0,"SetAutoCmd:" + Pid + ":" + Commonfunc.bytesToHexString(Pbuf, 0, Plen));
			return true;
		}
		else
			return false;
	}
	//设置P-CAN或B-CAN
	public boolean setCanMode(int mode){
		byte [] cmd = new byte[]{0x55,(byte) 0xAA,(byte) 0xC1,(byte) 0xB1,0x00,0x04,0x10,0x09,0x00,0x00};
		byte [] Ans = new byte[512];
		//记录设置CAN
		if(mLog != null) mLog.printMessage(0,"SetCan:" + mode);
		cmd[8] = (byte) (mode & 0xFF);
		cmd[9] = Commonfunc.calcuCheckCode(cmd, 4, 9);
		int rlen = sendOneToOne(cmd,cmd.length, Ans,Common.SET_MAX_TIME);
		return rlen > 0 && (Ans[6] == (byte) (cmd[6] + 0x40));
	}

	//设置can过滤
	public boolean setCanFilter(byte [] Pbuf,int num,String module){
		byte [] cmd = new byte[]{0x55,(byte) 0xAA,(byte) 0xC1,(byte) 0xB1,0x00,0x08,0x10,0x04,0x00,0x00,0x00,0x00,0x00,0x00};
		byte [] Ans = new byte[512];
		if(mLog != null){
			mLog.printMessage(0,"SetCanID:" + Commonfunc.bytesToHexStringSpace(Pbuf, 0, num * 2)+"--"+module);
			mLog.setCanId(Pbuf);
		}
		cmd[8] = (byte) (num & 0xFF);
		for(int i = 0; i < num * 2; i ++){
			cmd[9 + i] = Pbuf[i];
		}
		cmd[9 + num*2] = Commonfunc.calcuCheckCode(cmd, 4, 9 + num * 2);
		int rlen = sendOneToOne(cmd,cmd.length, Ans, Common.SET_MAX_TIME);
		return rlen > 0 && (Ans[6] == (byte) (cmd[6] + 0x40));
	}
	//设置can过滤
	public boolean SetCanFilter(byte [] Pbuf,int num)
	{
		byte [] cmd = new byte[]{0x55,(byte) 0xAA,(byte) 0xC1,(byte) 0xB1,0x00,0x08,0x10,0x04,0x00,0x00,0x00,0x00,0x00,0x00};
		byte [] Ans = new byte[128];
		//记录设置CAN ID
		if(mLog != null)
		{
			mLog.PrintAppend(0,"SetCanID:" + Commonfunc.bytesToHexString(Pbuf, 0, num * 2));
			mLog.setCanId(Pbuf); //设置canID
		}
		//
		cmd[8] = (byte) (num & 0xFF);
		for(int i = 0; i < num * 2; i ++)
		{
			cmd[9 + i] = Pbuf[i];
		}
		//计算校验
		cmd[9 + num*2] = Commonfunc.CalcChechSum(cmd, 4, 9 + num * 2);
		int rlen = SendOneToOne(cmd, cmd.length, Ans, Ans.length, Common.SET_MAX_TIME);
		if(rlen > 0 && (Ans[6] == (byte) (cmd[6] + 0x40)))
			return true;
		else
			return false;
	}

	//设置can自动回复
	public boolean setCanAutoFrame(byte [] Pbuf,int Plen){
		byte [] cmd = new byte[]{0x55,(byte) 0xAA,(byte) 0xC1,(byte) 0xB1,0x00,0x0B,0x10,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
		byte [] Ans = new byte[512];
		for(int i = 0; i < Plen; i ++){
			cmd[8 + i] = Pbuf[i];
		}
		cmd[8 + Plen] = Commonfunc.calcuCheckCode(cmd, 4, 8 + Plen);
		int rlen = sendOneToOne(cmd, cmd.length, Ans, Common.SET_MAX_TIME);
		return rlen > 0 && (Ans[6] == (byte)(cmd[6] + 0x40));
	}

	//设置时序
	public boolean setCommunTimer(int P1,int P2,int P3,int P4){
		byte [] cmd = new byte[]{0x55,(byte) 0xAA,(byte) 0xC1,(byte) 0xB1,0x00,0x09,0x10,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
		byte [] Ans = new byte[512];
		cmd[8] = (byte) (P1 & 0xFF);
		cmd[9] = (byte) ((P2 / 0x100) & 0xFF);
		cmd[10] = (byte) (P2 & 0xFF);
		cmd[11] = (byte) ((P3 / 0x100) & 0xFF);
		cmd[12] = (byte) (P3 & 0xFF);
		cmd[13] = (byte) (P4 & 0xFF);
		cmd[14] = Commonfunc.calcuCheckCode(cmd, 4, 14);
		int rlen = sendOneToOne(cmd, cmd.length, Ans, Common.SET_MAX_TIME);
		return rlen > 0 && (Ans[6] == (byte) (cmd[6] + 0x40));
	}

	//KWP波特率设置
	public boolean setKwpBaud(long baud,int kwpmode){
		byte [] cmd = new byte[]{0x55,(byte) 0xAA,(byte) 0xC1,(byte) 0xB1,0x00,0x06,0x10,0x02,0x00,0x00,0x02,0x00};
		byte [] Ans = new byte[512];
		if(mLog != null) mLog.printMessage(0,"SetkwpBaud:" + baud);
		//获取波特率
		cmd[8] = (byte) ((baud / 0x100) & 0xFF);
		cmd[9] = (byte) (baud & 0xFF);
		//设置KWP模式
		cmd[10] = (byte) kwpmode;
		cmd[11] = Commonfunc.calcuCheckCode(cmd, 4, 11);
		int rlen = sendOneToOne(cmd, cmd.length, Ans, Common.SET_MAX_TIME);
		return rlen > 0 && (Ans[6] == (byte) (cmd[6] + 0x40));
	}

	//获取OBD序列号
	public boolean getObdSerialNum(byte [] Serialnum, byte[] softver){
		byte [] cmd = new byte[]{0x55,(byte) 0xAA,(byte) 0xC1,(byte) 0xB1,0x00,0x03,0x20,0x08,0x00};
		byte [] ans = new byte[512];
		cmd[8] = Commonfunc.calcuCheckCode(cmd, 4, 8);
		int rlen = sendOneToOne(cmd, cmd.length, ans, Common.SET_MAX_TIME);
		if(rlen > 0 && (ans[6] == (byte) (cmd[6] + 0x40))){
			System.arraycopy(ans, 8, Serialnum, 0, 12);
			System.arraycopy(ans, 22,softver, 0, 2);
			return true;
		}
		return false;
	}

	/**
	 * 发多帧收多帧
	 * @param send 发送报文
	 * @param recv 接收报文
	 * @param maxtime 超时时间
	 * @return 返回结果
	 */
	public int canSendAndRecvN2N(byte[] send, byte[] recv, int maxtime){
//		if(mLog != null)//记录发送的数据
//			mLog.printMessage(1,Commonfunc.bytesToHexStringSpace(send,0,send.length));
//		if(Common.DEBUG) return 0;
		byte [] readbuf = new byte[512];
		int iRet = 0;
		for(int i = 0; i < Common.CMD_REQUEST; i ++){
			iRet = canSendMore2More(send, readbuf, maxtime);
			if(iRet > 0) break;
			if(i == Common.CMD_REQUEST - 1) return 5001;
			Commonfunc.sleep(Common.WAIT_TIME);
		}
		if(iRet > recv.length) iRet = recv.length - 1;
		System.arraycopy(readbuf,0, recv, 0, iRet);//复制接收数据
		Commonfunc.sleep(Common.WAIT_TIME);
		return (readbuf[1] & 0xFF) == ((send[1] + 0x40)&0xFF) ? 0 : 5002;
	}

	//ECU刷写
	public int CanSendAndRecvN2N_Flash(byte [] send,int Plen,byte [] recv,int Psize, int maxtime){
		byte [] readbuf = new byte[512];
		int i,iRet = 0;
		for(i = 0; i < Common.CMD_REQUEST; i ++){
			iRet = CanSendMore2More_Flash(send,Plen,readbuf,readbuf.length,maxtime);
			if(iRet > 0) break;
			if(i == Common.CMD_REQUEST-1) return 5001;
			Commonfunc.sleep(Common.WAIT_TIME);
		}
		if(iRet > recv.length) iRet =recv.length-1;
		System.arraycopy(readbuf,0,recv,0,iRet);//复制接收数据
		Commonfunc.sleep(Common.WAIT_TIME);
		return (readbuf[1]&0xFF)==((send[1]+0x40)&0xFF) ? 0 : 5002;
	}

	//cmd CAN 发多帧收多帧刷写
	private int CanSendMore2More_Flash(byte[] send,int Plen,byte [] recv,int Psize,int maxtime){
		byte [] cmd = new byte[]{0x11,0x33};
		byte [] data = new byte[5120];
		if(mLog != null){//记录发送的数据
			if(Plen>30){//只记录前30个字节
				mLog.printMessage(1,Commonfunc.bytesToHexString(send, 0, 30));
			}else{
				mLog.printMessage(1,Commonfunc.bytesToHexString(send, 0, Plen));
			}
		}
		data[0] = (byte) ((maxtime / 0x100) & 0xFF);
		data[1] = (byte) (maxtime & 0xFF);
		//添加发送命令的帧数以及帧内容
		int framenum = 0;
		if(Plen <= 8) { //单帧
			framenum = 1;
			for (int i = 0; i < Plen; i ++){
				data[4 + i] = send[i];
			}
		}else{ //多帧
			framenum = (Plen + 6) / 7;
			if (framenum > 600){ //越界
				return 0;
			}
			for (int i = 0; i < framenum - 1; i ++){
				if (i == 0)
					data[4 +i * 8] = (byte) (0x10+((Plen/256)&0xFF));
				else
					data[4 +i * 8] = (byte) (0x20 + i % 0x10);
				for (int j = 0; j < 7; j ++){//添加内容
					data[4 +i * 8 + 1+j] = send[i * 7 + j];
				}
			}
			//复制最后一帧
			data[4 +(framenum - 1) * 8] = (byte) (((framenum - 1) & 0x0F) + 0x20);
			int lastlen = Plen % 7;
			if(lastlen == 0) lastlen = 7;
			for (int j = 0; j < lastlen; j ++) {
				data[4 +(framenum - 1) * 8 + 1+j] = send[(framenum - 1) * 7 + j];
			}
		}

		data[2] = (byte)(framenum / 0x100); //帧数
		data[3] = (byte)(framenum % 0x100); //帧数
		byte [] Sendbuf = new byte [5120];
		int Sendlen = addData2Cmd(cmd, data, framenum * 8 + 4, Sendbuf);
		byte [] Readbuf = new byte[128];
		int iRet = sendOneToOne(Sendbuf, Sendlen, Readbuf,Common.CMD_MAX_TIME);
		if(iRet == 9){ //只收到发送成功数据
			if (Readbuf[0] == 0x55 && (Readbuf[6] == cmd[0]) && (Readbuf[7] == cmd[1])){ //命令发送成功

				iRet = readData(Readbuf, maxtime + 800);//继续接收命令
				if (iRet > 0){
					if (Readbuf[0] == 0x55 && ((Readbuf[6] & 0xFF) == cmd[0] + 0x40) && (Readbuf[7] == cmd[1])){
						iRet = (Readbuf[4] * 0x100 + Readbuf[5]) - 3;//返回长度
						if (Readbuf[8] == 1){ ////拆开CAN包重组CAN数据
							iRet = Readbuf[10] + 1;
							for(int i = 0;i < iRet; i ++)
								recv[i] = Readbuf[10 + i];
						}else if (Readbuf[8] > 1){ //多帧
							iRet = Readbuf[11] + 1;
							int j;
							for(int i = 0; i < Readbuf[8]; i ++){
								for (j = 0; j < 7; j ++){
									recv[i * 7 + j] = Readbuf[9 + i * 9 + 2 + j];
								}
							}
						}
					}else iRet = 0;
				}else iRet = 0;
			}else iRet = 0;
		}else if(iRet > 9){ //一次性接收回来完了
			if(Readbuf[9] == 0x55 && ((Readbuf[15] & 0xFF) == cmd[0] + 0x40) && (Readbuf[16] == cmd[1])){
				iRet = (Readbuf[13] * 0x100 + Readbuf[14]) - 3;//返回长度
				if (Readbuf[17] == 1){ //单帧 拆开CAN包重组CAN数据
					iRet = Readbuf[19] + 1;
					for(int i = 0;i < iRet; i ++)
						recv[i] = Readbuf[19 + i];
				}else if (Readbuf[17] > 1){ //多帧
					iRet = Readbuf[20] + 1;
					int j;
					for(int i = 0; i < Readbuf[17]; i ++){
						for (j = 0; j < 7; j ++){
							recv[i * 7 + j] = Readbuf[18 + i * 9 + 2 + j];
						}
					}
				}
			}else iRet = 0;

		}else iRet = 0;
		if(mLog != null && iRet > 0){//记录接收的数据
			mLog.printMessage(2, Commonfunc.bytesToHexString(recv, 0, iRet));
		}
		return iRet;
	}

	/**
	 * CAN发一帧收一帧，不判断返回值
	 * @param send 发送报文
	 * @param recv 接收报文
	 * @param maxtime 超时时间
	 * @return 不判断接收结果
	 */
	public int canSendAndRecvO2O_Spec1(byte[] send,byte[] recv,int maxtime){
		byte [] readbuf = new byte[512];
		int iRet = 0;
		for(int i = 0; i < Common.CMD_REQUEST; i ++)
		{
			//iRet = canSendOne2One(send,readbuf, maxtime);
			if(iRet > 0) break;
			if(i == Common.CMD_REQUEST-1) return 5001;
			Commonfunc.sleep(Common.WAIT_TIME);
		}
		if(iRet >recv.length) iRet =recv.length- 1;
		System.arraycopy(readbuf, 0,recv, 0, iRet);
		Commonfunc.sleep(Common.WAIT_TIME);
		return 0;
	}

	//cmd使用can重发3次,发多帧收多帧
	public int canSendAndRecvN2N_LongTime(byte[] send,byte[] recv,int maxtime){
		byte[] readbuf = new byte[512];
		int iRet = 0;
		for(int i = 0; i < Common.CMD_REQUEST; i ++){
			iRet = canSendMore2More_LongTime(send,readbuf,maxtime);
			if(iRet > 0) break;
			if(i == Common.CMD_REQUEST-1) return 5001;
			Commonfunc.sleep(Common.WAIT_TIME);
		}
		if(iRet >recv.length) iRet =recv.length- 1;
		System.arraycopy(readbuf,0,recv, 0, iRet);//复制接收数据
		Commonfunc.sleep(Common.WAIT_TIME);
		return (readbuf[1]&0xFF)==((send[1] + 0x40)&0xFF)?0:1;
	}

	//cmd CAN 发多帧收多帧
	private int canSendMore2More(byte[] send,byte [] recv,int maxtime){
		byte [] cmd = new byte[]{0x11,0x31};
		byte [] data = new byte[512];
		if(mLog != null)//记录发送的数据
			mLog.printMessage(1,Commonfunc.bytesToHexStringSpace(send,0,send.length));
		data[0] = (byte) ((maxtime / 0x100) & 0xFF);
		data[1] = (byte) (maxtime & 0xFF);
		//添加发送命令的帧数以及帧内容
		int framenum =1;
		if(send.length <= 8){//单帧
			for (int i = 0; i <send.length; i ++){
				data[3 + i] = send[i];//添加一帧数据
			}
		}else{//多帧
			framenum = (send.length+ 6) / 7;
			if(framenum > 15) return 0;//越界
			for (int i = 0; i < framenum - 1; i ++){
				//添加帧头
				data[3 +i * 8]=i==0?0x10:(byte)(0x20 + i % 0x10);
				for (int j = 0; j < 7; j ++){//添加内容
					data[3 +i * 8 + 1+j] = send[i * 7 + j];
				}
			}
			//复制最后一帧 帧头
			data[3 +(framenum - 1) * 8] = (byte) (((framenum - 1) & 0x0F) + 0x20);
			int lastlen = send.length% 7;
			if(lastlen == 0) lastlen = 7;
			for (int j = 0; j < lastlen; j ++){
				data[3 +(framenum - 1) * 8 + 1+j] = send[(framenum - 1) * 7 + j];
			}
		}
		data[2] = (byte)framenum;//获取帧数
		byte [] Sendbuf = new byte [128];//组合成命令
		int Sendlen = addData2Cmd(cmd,data,framenum * 8+3,Sendbuf);
		if(Common.DEBUG) {
			Log.i(TAG,"Send:" + Commonfunc.bytesToHexStringSpace(send, 0,send.length));
			Log.i(TAG,"Cmd:" + Commonfunc.bytesToHexStringSpace(Sendbuf,0,Sendlen));
		}
		byte [] readbuf = new byte[128];
		int iRet = sendOneToOne(Sendbuf,Sendlen, readbuf,Common.CMD_MAX_TIME);
		if(iRet == 9){ //只收到发送成功数据
			if (readbuf[0] == 0x55 && (readbuf[6] == cmd[0]) && (readbuf[7] == cmd[1])){ //命令发送成功
				iRet = readData(readbuf,maxtime + 800);//继续接收命令
				if (iRet > 0){
					if (readbuf[0] == 0x55 && ((readbuf[6] & 0xFF) == cmd[0] + 0x40) && (readbuf[7] == cmd[1])){
						iRet = (readbuf[4] * 0x100 + readbuf[5]) - 3;//返回长度
						//拆开CAN包重组CAN数据
						if (readbuf[8] == 1){ //单帧
							iRet = readbuf[10] + 1;
							for(int i = 0;i < iRet; i ++)
								recv[i] = readbuf[10 + i];
						}else if (readbuf[8] > 1){ //多帧
							iRet = readbuf[11] + 1;
							int j;
							for(int i = 0; i < readbuf[8]; i ++){
								for (j = 0; j < 7; j ++){
									recv[i * 7 + j] = readbuf[9 + i * 9 + 2 + j];
								}
							}
						}
					}else iRet = 0;
				}else
					iRet = 0;
			}else
				iRet = 0;
		}else if(iRet > 9){ //一次性接收回来完了
			if(readbuf[9] == 0x55 && ((readbuf[15] & 0xFF) == cmd[0] + 0x40) && (readbuf[16] == cmd[1])){
				iRet = (readbuf[13] * 0x100 + readbuf[14]) - 3;//返回长度
				//拆开CAN包重组CAN数据
				if (readbuf[17] == 1){ //单帧
					iRet = readbuf[19] + 1;
					for(int i = 0;i < iRet; i ++)
						recv[i] = readbuf[19 + i];
				}else if (readbuf[17] > 1){ //多帧
					iRet = readbuf[20] + 1;
					int j;
					for(int i = 0; i < readbuf[17]; i ++){
						for (j = 0; j < 7; j ++){
							recv[i * 7 + j] = readbuf[18 + i * 9 + 2 + j];
						}
					}
				}
			}else
				iRet = 0;
		}else
			iRet = 0;
		if(mLog != null && iRet > 0)//记录接收的数据
			mLog.printMessage(2,Commonfunc.bytesToHexStringSpace(recv, 0, iRet));
		return iRet;
	}
	//-1 -- 断网; -2 -- 超时; -3 -- IO异常; -4 -- 校验失败; -5 -- box异常
	private int CanOne2OneUDS(int Preq,int Pres,byte[] send,int Plen,byte [] recv,int maxtime)
	{
		byte [] cmd = new byte[]{0x11,0x30};
		int framenum = 0;
		if(Plen > 20)
		{
			Commonfunc.sleep(1);
		}
		if(Plen <= 8)
		{
			framenum = 1;
		}
		else if(Plen <= 0x100)
		{
			framenum = (Plen + 6) / 7;
		}
		else
			framenum = (Plen + 5) / 7;
		byte [] data = new byte[10 + framenum * 8];
		Arrays.fill(data, (byte) 0);
		//记录发送的数据
		if(mLog != null){
			String result=Commonfunc.bytesToHexStringSpace(send, 0, Plen);
			mLog.PrintAppend(Preq,result);
		}
		//超时时间
		data[0] = (byte) ((maxtime / 0x100) & 0xFF);
		data[1] = (byte) (maxtime & 0xFF);
		//send id
		data[2] = (byte) (Preq / 0x100);
		data[3] = (byte) (Preq % 0x100);
		//recv id
		data[4] = (byte) (Pres / 0x100);
		data[5] = (byte) (Pres % 0x100);
		//特征报文
		data[6] = 0;
		data[7] = 0;
		//添加发送命令的帧数以及帧内容
		data[8] = (byte) (framenum / 0x100);
		data[9] = (byte) (framenum % 0x100);
		//添加内容
		int k = 0;
		if(Plen <= 0x100) //1位长度
		{
			if(Plen <= 8)
			{
				System.arraycopy(send, 0, data, 10, Plen);
			}
			else
			{
				//第一帧
				data[10] = 0x10;
				System.arraycopy(send, 0, data, 11, 7);
				for(k = 1; k < framenum - 1; k ++)
				{
					data[10 + k * 8] = (byte) (0x20 + k % 0x10);
					System.arraycopy(send, k * 7, data, 11 + k * 8, 7);
				}
				//last
				k = (framenum - 1);
				data[10 + k * 8] = (byte) (0x20 + k % 0x10);
				int v_lastlen = Plen % 7;
				if(v_lastlen == 0)
					v_lastlen = 7;
				System.arraycopy(send, k * 7, data, 11 + k * 8, v_lastlen);
			}
		}
		else
		{
			//第一帧
			data[10] = (byte) (0x10 + send[0]);
			System.arraycopy(send, 1, data, 11, 7);
			for(k = 1; k < framenum - 1; k ++)
			{
				data[10 + k * 8] = (byte) (0x20 + k % 0x10);
				System.arraycopy(send, 1 + k * 7, data, 11 + k * 8, 7);
			}
			//last
			k = (framenum - 1);
			data[10 + k * 8] = (byte) (0x20 + k % 0x10);
			int v_lastlen = (Plen - 1) % 7;
			if(v_lastlen == 0)
				v_lastlen = 7;
			System.arraycopy(send, 1 + k * 7, data, 11 + k * 8, v_lastlen);
		}

		//组合成命令
		byte [] Sendbuf = new byte [9 + data.length];
		int Sendlen = addData2Cmd(cmd, data, data.length, Sendbuf);

		//发送
		byte [] Readbuf = new byte[512];
		//int iRet = SendOneToOne(Sendbuf, Sendlen, Readbuf, Readbuf.length, Common.cmdmaxtime);
		int iRet =SendOneToOneNew(Sendbuf, Sendlen, Readbuf, Readbuf.length, maxtime);
		if(iRet != 9) //nok
		{
			if(iRet >= 0) //
				iRet = -5;
			return iRet;
		}
		//接收数据
		while(true)
		{
			iRet = ReaddataComplete(Readbuf, Readbuf.length, maxtime + 500);
			if(iRet > 9) //ok
			{
				if((Readbuf[5] == 0x0D) && (Readbuf[10] == 0x03) && (Readbuf[11] == 0x7F) && (Readbuf[13] == 0x78)) //wait
				{
					if(mLog != null){
						mLog.PrintAppend(Pres,Commonfunc.bytesToHexStringSpace(Readbuf, 10, 14));
					}
					if(maxtime < 5000)
						maxtime = 5000;
					Commonfunc.sleep(10);
					continue;
				}
				else //拷贝数据
				{
					//拆开CAN包重组CAN数据
					if((Readbuf[8]&0xFF) > 20) break;
					if (Readbuf[8] == 1) //单帧
					{
						iRet = Readbuf[10] + 1;
						for(int i = 0;i < iRet; i ++)
							recv[i] = Readbuf[10 + i];
					}
					else if (Readbuf[8] > 1) //多帧
					{
						iRet = ((Readbuf[10]&0x0F) << 8) + (Readbuf[11]&0xFF) + 1;
						for(int i = 0; i < Readbuf[8]; i ++)
						{
							System.arraycopy(Readbuf,9 + i * 9 + 2, recv, i * 7, 7);
						}
					}
					break;
				}
			}
			else if(iRet == 9 && Readbuf[6] == 0x6F && Readbuf[7] == 0x02) //timeout
			{
				iRet = -2; break;
			}
			else
				break;
		}

		//记录接收的数据
		if(mLog != null){
			if(iRet > 0) {
				String result = Commonfunc.bytesToHexStringSpace(recv, 0, iRet);
				mLog.PrintAppend(Pres,Commonfunc.bytesToHexStringSpace(recv, 0, iRet));
			}
			else
			{
				if(iRet == -1)
					mLog.PrintAppend(0, "Connect Lost!");
				else if(iRet == -2)
				{
					mLog.PrintAppend(0, "Time out!");
					iRet = 0;
				}
				else if(iRet == -3)
					mLog.PrintAppend(0, "IOException!");
				else  if(iRet == -4)
				{
					mLog.PrintAppend(0, "Check failed!");
					iRet = 0;
				}
				else  if(iRet == -5)
					mLog.PrintAppend(0, "Box error!");
				else
					mLog.PrintAppend(0, "Else error!");
			}
		}
		return iRet;
	}

	//cmd CAN 发多帧收多帧,特殊处理超长时间收数据
	private int canSendMore2More_LongTime(byte[] send,byte [] recv,int maxtime){
		byte [] cmd = new byte[]{0x11,0x31};
		byte [] data = new byte[512];
		if(mLog != null)//记录发送的数据
			mLog.printMessage(1,Commonfunc.bytesToHexStringSpace(send, 0, send.length));
		data[0] = (byte) ((maxtime / 0x100) & 0xFF);//超时时间
		data[1] = (byte) (maxtime & 0xFF);
		//添加发送命令的帧数以及帧内容
		int framenum = 1;
		if(send.length <= 8){ //单帧
			for (int i = 0; i < send.length; i ++){
				data[3 + i] = send[i];//添加一帧数据
			}
		}else{//多帧
			framenum = (send.length + 6) / 7;
			if (framenum > 15){ //越界
				return 0;
			}
			for (int i = 0; i < framenum - 1; i ++){
				//添加帧头
				data[3 +i * 8]=i==0?0x10:(byte) (0x20 + i % 0x10);
				for (int j = 0; j < 7; j ++){//添加内容
					data[3 +i * 8 + 1+j] = send[i * 7 + j];
				}
			}
			//复制最后一帧//帧头
			data[3 +(framenum - 1) * 8] = (byte) (((framenum - 1) & 0x0F) + 0x20);
			int lastlen = send.length % 7;
			if(lastlen == 0) lastlen = 7;
			for (int j = 0; j < lastlen; j ++){
				data[3 +(framenum - 1) * 8 + 1+j] = send[(framenum - 1) * 7 + j];
			}
		}
		data[2] = (byte)framenum;//获取帧数
		byte [] Sendbuf = new byte [128];//组合成命令
		int Sendlen = addData2Cmd(cmd, data, framenum * 8 + 3, Sendbuf);
		if(Common.DEBUG) {
			Log.i(TAG,"Sed:" + Commonfunc.bytesToHexStringSpace(send, 0,send.length));
			Log.i(TAG,"Cmd:" + Commonfunc.bytesToHexStringSpace(Sendbuf, 0,Sendlen));
		}
		//发送
		byte [] readbuf = new byte[128];
		int iRet = sendOneToOne(Sendbuf, Sendlen, readbuf,Common.CMD_MAX_TIME);
		if(iRet == 9){ //只收到发送成功数据
			if (readbuf[0] == 0x55 && (readbuf[6] == cmd[0]) && (readbuf[7] == cmd[1])){ //命令发送成功
				iRet = readData(readbuf,maxtime + 20000);//继续接收命令
				if (iRet > 0){
					if (readbuf[0] == 0x55 && ((readbuf[6] & 0xFF) == cmd[0] + 0x40) && (readbuf[7] == cmd[1])){
						iRet = (readbuf[4] * 0x100 + readbuf[5]) - 3;//返回长度
						//拆开CAN包重组CAN数据
						if (readbuf[8] == 1){ //单帧
							iRet = readbuf[10] + 1;
							for(int i = 0;i < iRet; i ++)
								recv[i] = readbuf[10 + i];
						}else if (readbuf[8] > 1){ //多帧
							iRet = readbuf[11] + 1;
							int j;
							for(int i = 0; i < readbuf[8]; i ++){
								for (j = 0; j < 7; j ++){
									recv[i * 7 + j] = readbuf[9 + i * 9 + 2 + j];
								}
							}
						}
					}else iRet = 0;
				}else
					iRet = 0;
			}else
				iRet = 0;
		}else if(iRet > 9){ //一次性接收回来完了
			if(readbuf[9] == 0x55 && ((readbuf[15] & 0xFF) == cmd[0] + 0x40) && (readbuf[16] == cmd[1])){
				iRet = (readbuf[13] * 0x100 + readbuf[14]) - 3;//返回长度
				//拆开CAN包重组CAN数据
				if (readbuf[17] == 1){ //单帧
					iRet = readbuf[19] + 1;
					for(int i = 0;i < iRet; i ++)
						recv[i] = readbuf[19 + i];
				}else if (readbuf[17] > 1){//多帧
					iRet = readbuf[20] + 1;
					int j;
					for(int i = 0; i < readbuf[17]; i ++){
						for (j = 0; j < 7; j ++){
							recv[i * 7 + j] = readbuf[18 + i * 9 + 2 + j];
						}
					}
				}
			}else
				iRet = 0;
		}else
			iRet = 0;
		if(mLog != null && iRet > 0)//记录接收的数据
			mLog.printMessage(2,Commonfunc.bytesToHexStringSpace(recv, 0, iRet));
		return iRet;
	}

	public int canSendAndRecvO2O(short SendId, short RecvId,byte [] send,byte [] recv, int maxtime){
		byte [] readbuf = new byte[256];
		int i,iRet = 0;
		for(i = 0; i < Common.CMD_REQUEST; i ++){
			iRet = canSendOne2One(SendId, RecvId, send, readbuf,maxtime);
			if(iRet > 0) break;
			if(i == Common.CMD_REQUEST-1) return 5001;
			Commonfunc.sleep(Common.WAIT_TIME);
		}
		if(iRet > recv.length) iRet = recv.length - 1;
		System.arraycopy(readbuf,0, recv, 0, iRet);//复制接收数据
		return (readbuf[1]&0xFF)==((send[1]+0x40)&0xFF) ? 0 : 5002;
	}
	public int CanOne2OneUDS(int Preq,int Pres,byte [] Send,int Plen,byte [] Recv,int Perror,int Pmaxtime,int Pfreq)
	{
		int error = 0;
		int i;
		for(i = 0; i < Pfreq; i ++)
		{
			error = CanOne2OneUDS(Preq,Pres,Send,Plen,Recv,Pmaxtime);
			if(error > 0) break;
			else if(error < 0)
			{
				error = 5002;
			}
			if(exit) return 5002;
			Commonfunc.sleep(Common.WAIT_TIME);
		}
		if(i >= Pfreq) error = 5001; //无响应
		return error;
	}
	//CAN发一帧收一帧，不判断返回值
	public int canSendAndRecvO2O_Spec(short SendId,short RecvId,byte [] send,byte [] recv, int maxtime){
		byte [] readbuf = new byte[256];
		int i,iRet = 0;
		for(i = 0; i < Common.CMD_REQUEST; i ++)
		{
			iRet = canSendOne2One(SendId,RecvId,send,readbuf,maxtime);
			if(iRet > 0) break;
			if(exit) return 5002;
			Commonfunc.sleep(Common.WAIT_TIME);
		}
		if(i >= Common.CMD_REQUEST) return 5001; //无响应

		if(iRet > recv.length) iRet = recv.length - 1;
		System.arraycopy(readbuf,0, recv, 0, iRet);//复制接收数据
		return 0;
	}
	//获取序列号
	public boolean GetSerialNum(byte [] Serialnum,int Psize,byte[] softver)
	{
		byte [] cmd = new byte[]{0x55,(byte) 0xAA,(byte) 0xC1,(byte) 0xB1,0x00,0x03,0x20,0x08,0x00};
		byte [] Ans = new byte[128];
		//计算校验
		cmd[8] = Commonfunc.CalcChechSum(cmd, 4, 8);
		int rlen = SendOneToOne(cmd, cmd.length, Ans, Ans.length, Common.SET_MAX_TIME);
		if(rlen > 0 && (Ans[6] == (byte) (cmd[6] + 0x40)))
		{
			System.arraycopy(Ans, 8, Serialnum, 0, 12);
			System.arraycopy(Ans, 22, softver, 0, 2);
			return true;
		}
		else
			return false;
	}

	public int CanSendAndRecvO2O_Spec(int Psid,int Prid,byte [] Send,int Plen,byte [] Recv,int Psize,int errorcode,int maxtime)
	{
		int error = 0;
		byte [] Readbuf = new byte[256];
		int i,iRet = 0;
		for(i = 0; i < Common.cmd_freq; i ++)
		{
			iRet = CanSendOne2One(Psid,Prid,Send,Plen,Readbuf,Readbuf.length,maxtime);
			if(iRet > 0) break;
			if(exit) return 5002;
			Commonfunc.sleep(Common.waittime);
		}
		if(i >= Common.cmd_freq) return 5001; //无响应
		//复制接收数据
		if(iRet > Psize)
			iRet = Psize - 1;
		System.arraycopy(Readbuf, 0, Recv, 0, iRet);
		return error;
	}
	private int CanSendOne2One(int Psid,int Prid,byte[] send,int Plen,byte [] recv,int Psize,int maxtime)
	{
		byte [] cmd = new byte[]{0x11,0x32};
		byte [] data = new byte[128];
		//记录发送的数据
		if(mLog != null){
			String result=Commonfunc.bytesToHexString(send, 0, Plen);
			mLog.PrintAppend(Psid,result);
		}
		//超时时间
		data[0] = (byte) ((maxtime / 0x100) & 0xFF);
		data[1] = (byte) (maxtime & 0xFF);
		//添加发送命令的帧数以及帧内容
		//send id
		data[2] = (byte) ((Psid >>> 8) & 0xFF);
		data[3] = (byte) (Psid &0xFF);
		//recv id
		data[4] = (byte) ((Prid >>> 8) & 0xFF);
		data[5] = (byte) (Prid &0xFF);
		//特征报文
		data[6] = 0x00;
		data[7] = 0x01;
		data[8] = (byte) 0xFF;
		//data 8bytes
		System.arraycopy(send, 0, data, 9, Plen);

		//组合成命令
		byte [] Sendbuf = new byte [128];
		int Sendlen = addData2Cmd(cmd, data, 17, Sendbuf);
		if(Common.Debug)
		{
			Log.i(TAG,"Sed:" + Commonfunc.bytesToHexString(send, 0,Plen));
			Log.i(TAG,"Cmd:" + Commonfunc.bytesToHexString(Sendbuf, 0,Sendlen));
		}
		//发送
		byte [] Readbuf = new byte[128];
		int iRet = SendOneToOne(Sendbuf, Sendlen, Readbuf, Readbuf.length, Common.CMD_MAX_TIME);
		if(iRet == 9) //只收到发送成功数据
		{
			if (Readbuf[0] == 0x55 && (Readbuf[6] == cmd[0]) && (Readbuf[7] == cmd[1])) //命令发送成功
			{
				//继续接收命令
				iRet = Readdata(Readbuf, Readbuf.length, maxtime + 800);
				if (iRet > 0)
				{
					if (Readbuf[0] == 0x55 && ((Readbuf[6] & 0xFF) == cmd[0] + 0x40) && (Readbuf[7] == cmd[1]))
					{
						iRet = (Readbuf[4] * 0x100 + Readbuf[5]) - 3;//返回长度
						//拆开CAN包重组CAN数据
						if (Readbuf[8] == 1) //单帧
						{
							iRet = 8;
							for(int i = 0;i < 8; i ++)
								recv[i] = Readbuf[10 + i];
						}
						else if (Readbuf[8] > 1) //多帧
						{
						}

					}
					else iRet = 0;
				}
				else
					iRet = 0;
			}
			else
				iRet = 0;
		}
		else if(iRet > 9) //一次性接收回来完了
		{
			if(Readbuf[9] == 0x55 && ((Readbuf[15] & 0xFF) == cmd[0] + 0x40) && (Readbuf[16] == cmd[1]))
			{
				iRet = (Readbuf[13] * 0x100 + Readbuf[14]) - 3;//返回长度
				//拆开CAN包重组CAN数据
				if (Readbuf[17] == 1) //单帧
				{
					iRet = 8;
					for(int i = 0;i < 8; i ++)
						recv[i] = Readbuf[19 + i];
				}
				else if (Readbuf[17] > 1) //多帧
				{
				}
			}
			else
				iRet = 0;
		}
		else
			iRet = 0;
		//记录接收的数据
		if(mLog != null && iRet > 0){
			mLog.PrintAppend(Prid,Commonfunc.bytesToHexString(recv, 0, iRet));
		}
		return iRet;
	}

	//CAN发一帧收一帧
	private int canSendOne2One(short SendId,short RecvId,byte[] send, byte [] recv,int maxtime){
		byte [] cmd = new byte[]{0x11,0x32};
		byte [] data = new byte[128];
		if(mLog != null)//记录发送的数据
			mLog.printMessage(1,Commonfunc.bytesToHexStringSpace(send,0,send.length));
		//超时时间
		data[0] = (byte) ((maxtime / 0x100) & 0xFF);
		data[1] = (byte) (maxtime & 0xFF);
		//send id
		data[2] = (byte) (SendId / 0x100);
		data[3] = (byte) (SendId % 0x100);
		//RecvId
		data[4] = (byte) (RecvId / 0x100);
		data[5] = (byte) (RecvId % 0x100);
		//特征字
		data[6] = 0;
		data[7] = 0;
		data[8] = 0;
		//添加发送命令的帧数以及帧内容
		int framenum = 0;
		if(send.length <= 8){ //单帧
			framenum = 1;
			//添加一帧数据
			for (int i = 0; i < send.length; i ++){
				data[9 + i] = send[i];
			}
		}else{

		}
		//组合成命令
		byte [] Sendbuf = new byte [128];
		int Sendlen = addData2Cmd(cmd, data, framenum * 8 + 9, Sendbuf);
		if(Common.DEBUG) {
			Log.i(TAG,"Send:" + Commonfunc.bytesToHexStringSpace(send, 0,send.length));
			Log.i(TAG,"Cmd:" + Commonfunc.bytesToHexStringSpace(Sendbuf,0,Sendlen));
		}
		byte [] Readbuf = new byte[128];
		int iRet = sendOneToOne(Sendbuf, Sendlen, Readbuf, Common.CMD_MAX_TIME);
		if(iRet == 9){ //只收到发送成功数据
			if (Readbuf[0] == 0x55 && (Readbuf[6] == cmd[0]) && (Readbuf[7] == cmd[1])){ //命令发送成功
				//继续接收命令
				iRet = readData(Readbuf, maxtime + 800);
				if (iRet > 0){
					if (Readbuf[0] == 0x55 && ((Readbuf[6] & 0xFF) == cmd[0] + 0x40) && (Readbuf[7] == cmd[1])){
						iRet = (Readbuf[4] * 0x100 + Readbuf[5]) - 3;//返回长度
						//拆开CAN包重组CAN数据
						if (Readbuf[8] == 1){ //单帧
							iRet = 8;
							for(int i = 0;i < 8; i ++)
								recv[i] = Readbuf[10 + i];
						}else if (Readbuf[8] > 1) //多帧
						{
						}

					}
					else iRet = 0;
				}
				else
					iRet = 0;
			}
			else
				iRet = 0;
		}else if(iRet > 9){ //一次性接收回来完了

			if(Readbuf[9] == 0x55 && ((Readbuf[15] & 0xFF) == cmd[0] + 0x40) && (Readbuf[16] == cmd[1])){
				iRet = (Readbuf[13] * 0x100 + Readbuf[14]) - 3;//返回长度
				//拆开CAN包重组CAN数据
				if (Readbuf[17] == 1){ //单帧
					iRet = 8;
					for(int i = 0;i < 8; i ++)
						recv[i] = Readbuf[19 + i];
				}else if (Readbuf[17] > 1){ //多帧
				}
			}
			else
				iRet = 0;
		}
		else
			iRet = 0;
		if(mLog != null && iRet > 0)//记录接收的数据
			mLog.printMessage(2,Commonfunc.bytesToHexStringSpace(recv, 0, iRet));
		return iRet;
	}
	//CAN发一帧收一帧
	private int CanSendOne2One_New(byte[] send,int Plen,byte [] recv,int Psize,int maxtime)
	{
		byte [] cmd = new byte[]{0x11,0x32};
		byte [] data = new byte[128];
		//记录发送的数据
		if(mLog != null){
			String result=Commonfunc.bytesToHexString(send, 0, Plen);
			mLog.PrintAppend(1,result);
		}
		//超时时间
		data[0] = (byte) ((maxtime / 0x100) & 0xFF);
		data[1] = (byte) (maxtime & 0xFF);
		//添加发送命令的帧数以及帧内容
		int framenum = 0;
		if(Plen <= 8) //单帧
		{
			framenum = 1;
			//添加一帧数据
			for (int i = 0; i < Plen; i ++)
			{
				data[3 + i] = send[i];
			}
		}
		else	//多帧
		{
			framenum = (Plen + 6) / 7;
			if (framenum > 15) //越界
			{
				return 0;
			}
			for (int i = 0; i < framenum - 1; i ++)
			{
				//添加帧头
				if (i == 0)
					data[3 +i * 8] = 0x10;
				else
					data[3 +i * 8] = (byte) (0x20 + i % 0x10);
				//添加内容
				for (int j = 0; j < 7; j ++)
				{
					data[3 +i * 8 + 1+j] = send[i * 7 + j];
				}
			}
			//复制最后一帧
			//帧头
			data[3 +(framenum - 1) * 8] = (byte) (((framenum - 1) & 0x0F) + 0x20);
			int lastlen = Plen % 7;
			if(lastlen == 0) lastlen = 7;
			for (int j = 0; j < lastlen; j ++)
			{
				data[3 +(framenum - 1) * 8 + 1+j] = send[(framenum - 1) * 7 + j];
			}
		}
		//获取帧数
		data[2] = (byte)framenum;
		//组合成命令
		byte [] Sendbuf = new byte [128];
		int Sendlen = addData2Cmd(cmd, data, framenum * 8 + 3, Sendbuf);
		if(Common.DEBUG)
		{
			Log.i(TAG,"Sed:" + Commonfunc.bytesToHexString(send, 0,Plen));
			Log.i(TAG,"Cmd:" + Commonfunc.bytesToHexString(Sendbuf, 0,Sendlen));
		}
		//发送
		byte [] Readbuf = new byte[128];
		int iRet = SendOneToOne(Sendbuf, Sendlen, Readbuf, Readbuf.length, Common.CMD_MAX_TIME);
		if(iRet == 9) //只收到发送成功数据
		{
			if (Readbuf[0] == 0x55 && (Readbuf[6] == cmd[0]) && (Readbuf[7] == cmd[1])) //命令发送成功
			{
				//继续接收命令
				iRet = Readdata(Readbuf, Readbuf.length, maxtime + 800);
				if (iRet > 0)
				{
					if (Readbuf[0] == 0x55 && ((Readbuf[6] & 0xFF) == cmd[0] + 0x40) && (Readbuf[7] == cmd[1]))
					{
						iRet = (Readbuf[4] * 0x100 + Readbuf[5]) - 3;//返回长度
						//拆开CAN包重组CAN数据
						if (Readbuf[8] == 1) //单帧
						{
							iRet = 8;
							for(int i = 0;i < 8; i ++)
								recv[i] = Readbuf[10 + i];
						}
						else if (Readbuf[8] > 1) //多帧
						{
						}

					}
					else iRet = 0;
				}
				else
					iRet = 0;
			}
			else
				iRet = 0;
		}
		else if(iRet > 9) //一次性接收回来完了
		{
			if(Readbuf[9] == 0x55 && ((Readbuf[15] & 0xFF) == cmd[0] + 0x40) && (Readbuf[16] == cmd[1]))
			{
				iRet = (Readbuf[13] * 0x100 + Readbuf[14]) - 3;//返回长度
				//拆开CAN包重组CAN数据
				if (Readbuf[17] == 1) //单帧
				{
					iRet = 8;
					for(int i = 0;i < 8; i ++)
						recv[i] = Readbuf[19 + i];
				}
				else if (Readbuf[17] > 1) //多帧
				{
				}
			}
			else
				iRet = 0;
		}
		else
			iRet = 0;
		//记录接收的数据
		if(mLog != null && iRet > 0){
			mLog.PrintAppend(2,Commonfunc.bytesToHexString(recv, 0, iRet));
		}
		return iRet;
	}
	///////////////////////////////////////////K线////////////////////////////////////////////////////////////////////////////////////
	//KWP快速初始化
	public int kwpFastConnect(int baud,int kwpmode,byte[] send,byte [] recv,int maxtime,int testtimes){
//		recv[0] = 10;
//		recv[1] = 0x33;
//		recv[2] = 0x30;
//		recv[3] = 0x31;
//		recv[4] = 0x34;
//		recv[5] = 0x33;
//		recv[6] = 0x34;
//		recv[7] = 0x36;
//		recv[8] = 0x37;
//		recv[9] = 0x34;
//		recv[10] = 0x36;
//		recv[11] = 0x37;
//		if(mLog != null)//记录发送的数据
//			mLog.printMessage(1,Commonfunc.bytesToHexStringSpace(send,0,send.length));
//		if(Common.DEBUG) return 0;//TODO
		int iRet = 0;
		for(int i = 0; i < Common.CMD_REQUEST; i ++){
			if(setKwpBaud(baud,kwpmode)) break;//设置波特率
			if(i==Common.CMD_REQUEST-1) return 5001;
			Commonfunc.sleep(Common.WAIT_TIME);
		}
		//先计算校验
		send[send.length - 1] = Commonfunc.calcuCheckCode(send, 0, send.length - 1);
		byte [] readbuf = new byte[512];
		for(int i = 0; i <testtimes; i ++){
			iRet = kwpFastInit((byte)0x19, (byte)0x19, send,readbuf,maxtime);
			if(iRet > 0) break;
			if(i==Common.CMD_REQUEST-1) return 5001;
			Commonfunc.sleep(Common.WAIT_TIME);
		}
		int r_Pos = 5;
		if((readbuf[2]&0xFF) == 0x80) r_Pos ++; //当收到0x80开头的
		int s_Pos = 3;
		if((send[0]&0xFF) == 0x80) s_Pos ++;

		if(iRet > recv.length) iRet = recv.length - 1;//复制接收数据
		System.arraycopy(readbuf, 0, recv, 0, iRet);
		Commonfunc.sleep(Common.WAIT_TIME);
		return readbuf[r_Pos] == (send[s_Pos] + 0x40) ? 0 : 5002;
	}

	//KWP快速初始化
	private int kwpFastInit(byte Plow,byte Phih,byte[] send,byte [] recv,int maxtime){
		byte [] cmd = new byte[]{0x11,0x01};
		byte [] data = new byte[512];
		if(mLog != null)//记录发送的数据
			mLog.printMessage(1,Commonfunc.bytesToHexStringSpace(send, 0, send.length));
		data[0] = (byte) ((maxtime / 0x100) & 0xFF);//超时时间
		data[1] = (byte) (maxtime & 0xFF);
		data[2] = Plow;//拉低拉高时间
		data[3] = Phih;
		System.arraycopy(send, 0, data, 4, send.length);//添加发送命令
		byte [] Sendbuf = new byte [128];//组合成命令
		int Sendlen = addData2Cmd(cmd, data, send.length + 4, Sendbuf);
		if(Common.DEBUG) {
			Log.i(TAG,"Sed:" + Commonfunc.bytesToHexStringSpace(send, 0,send.length));
			Log.i(TAG,"Cmd:" + Commonfunc.bytesToHexStringSpace(Sendbuf, 0,Sendlen));
		}
		byte [] readbuf = new byte[128];
		int iRet = sendOneToOne(Sendbuf, Sendlen, readbuf,Common.CMD_MAX_TIME);
		if(iRet == 9){//只收到发送成功数据
			if (readbuf[0] == 0x55 && (readbuf[6] == cmd[0]) && (readbuf[7] == cmd[1])){ //命令发送成功
				iRet = readData(readbuf,Common.CMD_MAX_TIME);//继续接收命令
				if (iRet > 0){
					if (readbuf[0] == 0x55 && ((readbuf[6] & 0xFF) == cmd[0] + 0x40) && (readbuf[7] == cmd[1])){
						iRet = (readbuf[4] * 0x100 + readbuf[5]) - 3;//返回长度
						//拆开数据
						recv[0] = 0x01;
						recv[1] = (byte) iRet;
						System.arraycopy(readbuf, 8, recv, 2, iRet);
						iRet += 2;
					}else iRet = 0;
				}else
					iRet = 0;
			}else
				iRet = 0;
		}else if(iRet > 9){ //一次性接收回来完了
			if(readbuf[9] == 0x55 && ((readbuf[15] & 0xFF) == cmd[0] + 0x40) && (readbuf[16] == cmd[1])){
				iRet = (readbuf[13] * 0x100 + readbuf[14]) - 3;//返回长度
				//拆开数据
				recv[0] = 0x01;
				recv[1] = (byte) iRet;
				System.arraycopy(readbuf, 17, recv, 2, iRet);
				iRet += 2;
			}else
				iRet = 0;
		}else
			iRet = 0;
		if(mLog != null && iRet > 0)//记录接收的数据
			mLog.printMessage(2,Commonfunc.bytesToHexStringSpace(recv, 0, iRet));
		return iRet;
	}

	//KWP快速初始化
	public int kwpOneToOne(byte[] send,byte [] recv,int maxtime,int testtimes){
//		recv[0] = 10;
//		recv[1] = 0x33;
//		recv[2] = (byte) 0x87;
//		recv[3] = 0x31;
//		recv[4] = 0x34;
//		recv[5] = 0x33;
//		recv[6] = 0x34;
//		recv[7] = 0x36;
//		recv[8] = 0x37;
//		recv[9] = 0x34;
//		recv[10] = 0x36;
//		recv[11] = 0x37;
//		if(mLog != null)//记录发送的数据
//			mLog.printMessage(1,Commonfunc.bytesToHexStringSpace(send,0,send.length));
//		if(Common.DEBUG) return 0;//TODO
		int iRet = 0;
		//先计算校验
		send[send.length - 1] = Commonfunc.calcuCheckCode(send, 0, send.length - 1);
		byte [] readbuf = new byte[256];
		for(int i = 0; i <testtimes; i ++){
			iRet = kwpSendOne2One(send,readbuf,maxtime);
			if(iRet > 0) break;
			if(i==Common.CMD_REQUEST-1) return 5001;
			Commonfunc.sleep(Common.WAIT_TIME);
		}
		int r_Pos = 5;
		if((readbuf[2]&0xFF) == 0x80) r_Pos ++; //当收到0x80开头的
		int s_Pos = 3;
		if((send[0]&0xFF) == 0x80) s_Pos ++;
		if(iRet > recv.length) iRet = recv.length - 1;//复制接收数据
		System.arraycopy(readbuf, 0, recv, 0, iRet);
		Commonfunc.sleep(Common.WAIT_TIME);
		return (readbuf[r_Pos]&0xFF) == ((send[s_Pos]&0xFF) + 0x40) ? 0 : 5002;
	}

	//KWP快速初始化
	private int kwpSendOne2One(byte[] send,byte [] recv,int maxtime){
		byte [] cmd = new byte[]{0x11,0x02};
		byte [] data = new byte[128];
		if(mLog != null)//记录发送的数据
			mLog.printMessage(1,Commonfunc.bytesToHexStringSpace(send, 0, send.length));
		data[0] = (byte) ((maxtime / 0x100) & 0xFF);//超时时间
		data[1] = (byte) (maxtime & 0xFF);
		System.arraycopy(send, 0, data, 2, send.length);//添加发送命令
		byte [] sendbuf = new byte [128];//组合成命令
		int Sendlen = addData2Cmd(cmd, data, send.length + 2, sendbuf);
		if(Common.DEBUG) {
			Log.i(TAG,"Sed:" + Commonfunc.bytesToHexStringSpace(send, 0,send.length));
			Log.i(TAG,"Cmd:" + Commonfunc.bytesToHexStringSpace(sendbuf, 0,Sendlen));
		}
		byte [] readbuf = new byte[256];
		int iRet = sendOneToOne(sendbuf, Sendlen, readbuf,Common.CMD_MAX_TIME);
		if(iRet == 9)	{ //只收到发送成功数据
			if (readbuf[0] == 0x55 && (readbuf[6] == cmd[0]) && (readbuf[7] == cmd[1])){ //命令发送成功
				iRet = readData(readbuf,Common.CMD_MAX_TIME);//继续接收命令
				if (iRet > 0){
					if (readbuf[0] == 0x55 && ((readbuf[6] & 0xFF) == cmd[0] + 0x40) && (readbuf[7] == cmd[1])){
						iRet = (readbuf[4] * 0x100 + readbuf[5]) - 3;//返回长度
						//拆开数据
						recv[0] = 0x01;
						recv[1] = (byte) iRet;
						System.arraycopy(readbuf, 8, recv, 2, iRet);
						iRet += 2;
					}else iRet = 0;
				}else
					iRet = 0;
			}else
				iRet = 0;
		}else if(iRet > 9){ //一次性接收回来完了
			if(readbuf[9] == 0x55 && ((readbuf[15] & 0xFF) == cmd[0] + 0x40) && (readbuf[16] == cmd[1])){
				iRet = (readbuf[13] * 0x100 + readbuf[14]) - 3;//返回长度
				//拆开数据
				recv[0] = 0x01;
				recv[1] = (byte) iRet;
				System.arraycopy(readbuf, 17, recv, 2, iRet);
				iRet += 2;
			}else
				iRet = 0;
		}else
			iRet = 0;
		if(mLog != null && iRet > 0)//记录接收的数据
			mLog.printMessage(2,Commonfunc.bytesToHexStringSpace(recv, 0, iRet));
		return iRet;
	}

	///////////////////////////////////////////扩展帧////////////////////////////////////////////////////////////////////////////////////
	//CAn扩展帧发多帧收多帧
	public int CanExtedMore2More(byte mode,byte Paddrstart,byte Paddrlength,byte[] SendId,byte[] RecvId,byte[] send,byte[] recv,int P2time,int maxtime){
//  		recv[0] = 10;
//		recv[1] = 0x33;
//		recv[2] = 0x30;
//		recv[3] = 0x31;
//		recv[4] = 0x34;
//		recv[5] = 0x33;
//		recv[6] = 0x34;
//		recv[7] = 0x36;
//		recv[8] = 0x37;
//		recv[9] = 0x34;
//		recv[10] = 0x36;
//		recv[11] = 0x37;
//		if(mLog != null)//记录发送的数据
//			mLog.printMessage(1,Commonfunc.bytesToHexStringSpace(send,0,send.length));
//		if(Common.DEBUG) return 0;//TODO
		int i,iRet = 0;
		for(i = 0; i < Common.CMD_REQUEST; i ++){
			iRet = canExtedSendMore2More(mode,Paddrstart,Paddrlength, SendId, RecvId, send, recv, P2time, maxtime);
			if(iRet > 0) break;
			if(exit) return 5002;
			Commonfunc.sleep(Common.WAIT_TIME);
		}
		if(i >= Common.CMD_REQUEST) return 5001; //无响应
		//复制接收数据
		if(iRet > recv.length) iRet = recv.length - 1;
		return iRet > 0 ? 0 : 5002;
	}

	/**
	 * @param mode 模式
	 * @param Paddrstart
	 * @param Paddrlength
	 * @param SendId 发送ID
	 * @param RecvId 接收ID
	 * @param send 发送数组
	 * @param recv 接收数组
	 * @param P2time 超时时间
	 * @param maxtime
	 * @return
	 */
	private int canExtedSendMore2More(byte mode,byte Paddrstart,byte Paddrlength,byte[] SendId,byte[] RecvId,byte[] send,byte[] recv,int P2time,int maxtime){
		byte [] cmd = new byte[]{0x11,0x35};
		byte [] data = new byte[512];
		Arrays.fill(data, (byte) 0x00);
		if(mLog != null)
			mLog.printMessage(3,Commonfunc.bytesToHexString(send, 0, send.length));
		//单帧多帧模式
		data[0] = mode;
		//P2时间
		data[1] = (byte) (P2time >>> 8);
		data[2] = (byte) P2time;
		//超时时间
		data[3] = (byte) ((maxtime / 0x100) & 0xFF);
		data[4] = (byte) (maxtime & 0xFF);
		//发送ID
		System.arraycopy(SendId, 0, data, 5, 4);
		//接收ID
		System.arraycopy(RecvId, 0, data, 9, 4);
		//特殊处理4byte
		data[13] = Paddrstart;
		data[14] = Paddrlength;
		data[15] = 0x00;
		data[16] = 0x00;
		//内容
		int framenum = 0;
		if(send.length <= 8){ //单帧

			framenum = 1;
			//添加一帧数据
			for (int i = 0; i < send.length; i ++){
				data[19 + i] = send[i];
			}
		}else{	//多帧
			framenum = (send.length + 7) / 8;
			if (framenum > 15){ //越界
				return 0;
			}
			for (int i = 0; i < framenum - 1; i ++){
				if (i == 0)
					data[19 +i * 8] = 0x10;
				else
					data[19 +i * 8] = (byte) (0x20 + i % 0x10);
				//添加内容
				for (int j = 0; j < 7; j ++){
					data[19 +i * 8 + 1+j] = send[i * 7 + j];
				}
			}
			//复制最后一帧
			//帧头
			data[19 +(framenum - 1) * 8] = (byte) (((framenum - 1) & 0x0F) + 0x20);
			int lastlen = send.length % 7;
			if(lastlen == 0) lastlen = 7;
			for (int j = 0; j < lastlen; j ++){
				data[19 +(framenum - 1) * 8 + 1+j] = send[(framenum - 1) * 7 + j];
			}
		}
		//帧数
		data[17] = (byte) (framenum >>>8);
		data[18] = (byte) framenum;
		//组合成命令
		byte [] Sendbuf = new byte [512];
		int Sendlen = addData2Cmd(cmd, data, 19 + framenum * 8, Sendbuf);
		//发送
		byte [] Readbuf = new byte[2048];
		int iRet = sendOneToOne(Sendbuf, Sendlen, Readbuf, Common.CMD_MAX_TIME);
		int v_frame = 0;
		if(iRet == 9){ //只收到发送成功数据
			if (Readbuf[0] == 0x55 && (Readbuf[6] == cmd[0]) && (Readbuf[7] == cmd[1])){ //命令发送成功
				//继续接收命令
				iRet = readData(Readbuf, maxtime + 1000);
				if (iRet > 0){
					if (Readbuf[0] == 0x55 && ((Readbuf[6] & 0xFF) == cmd[0] + 0x40) && (Readbuf[7] == cmd[1]))
					{
						iRet = (Readbuf[4] * 0x100 + Readbuf[5]) - 3;//返回长度
						//拆开CAN包重组CAN数据
						v_frame = (Readbuf[8]&0xFF) * 0x100 + (Readbuf[9]&0xFF);
						if(mode == 2) //连续多帧
						{
							iRet = v_frame*8 + 2;
							if(iRet > recv.length) iRet = recv.length -1;
							System.arraycopy(Readbuf, 8, recv, 0, iRet);
						}
					}
					else iRet = 0;
				}
				else
					iRet = 0;
			}
			else
				iRet = 0;
		}else if(iRet > 9){ //一次性接收回来完了
			if(Readbuf[9] == 0x55 && ((Readbuf[15] & 0xFF) == cmd[0] + 0x40) && (Readbuf[16] == cmd[1])){
				iRet = (Readbuf[13] * 0x100 + Readbuf[14]) - 3;//返回长度
				//拆开CAN包重组CAN数据
				v_frame = (Readbuf[17]&0xFF) * 0x100 + (Readbuf[18]&0xFF);
				if(mode == 2) //连续多帧
				{
					iRet = v_frame*8 + 2;
					if(iRet > recv.length) iRet = recv.length -1;
					System.arraycopy(Readbuf, 17, recv, 0, iRet);
				}
			}else
				iRet = 0;
		}else
			iRet = 0;
		//记录接收的数据
		if(mLog != null && iRet > 0){
			if(iRet > 30)
				mLog.printMessage(4,Commonfunc.bytesToHexString(recv, 0, 30));
			else
				mLog.printMessage(4,Commonfunc.bytesToHexString(recv, 0, iRet));
		}
		return iRet;
	}

	/**
	 * 扩展帧只读一帧数据
	 * @param mode 模式
	 * @param recv_id 接收ID
	 * @param recv 接收字节数组
	 * @param maxtime 超时时间
	 * @return 通讯结果
	 */
	public int canExtedOne2One(byte[] SendId,byte[] RecvId,byte[] send,byte[] recv,int maxtime){
		int i,iRet = 0;
		for(i = 0; i < Common.CMD_REQUEST; i ++){
			iRet = canExtedSendOne2One(SendId, RecvId, send, recv, maxtime);
			if(iRet > 0) break;
			if(exit) return 5002;
			Commonfunc.sleep(Common.WAIT_TIME);
		}
		if(i >= Common.CMD_REQUEST) return 5001; //无响应
		if(iRet > recv.length) iRet = recv.length - 1;
		return iRet > 0 ? 0 : 5002;
	}

	/**
	 * 扩展帧只读一帧数据
	 * @param mode 模式
	 * @param recv_id 接收ID
	 * @param recv 接收字节数组
	 * @param maxtime 超时时间
	 * @return 通讯结果
	 */
	private int canExtedSendOne2One(byte[] SendId,byte[] RecvId,byte[] send,byte[] recv,int maxtime){
		byte [] cmd = new byte[]{0x11,0x36};
		byte [] data = new byte[128];
		Arrays.fill(data, (byte) 0x00);
		//记录发送的数据
		if(mLog != null)
			mLog.printMessage(3,Commonfunc.bytesToHexString(send, 0,send.length));
		//超时时间
		data[0] = (byte) ((maxtime / 0x100) & 0xFF);
		data[1] = (byte) (maxtime & 0xFF);
		//发送ID
		System.arraycopy(SendId, 0, data, 2, 4);
		//接收ID
		System.arraycopy(RecvId, 0, data, 6, 4);
		//特殊处理4byte
		data[10] = 0x01;
		//内容
		if(send.length <= 8){ //单帧
			//添加一帧数据
			for (int i = 0; i < send.length; i ++){
				data[11 + i] = send[i];
			}
		}
		//组合成命令
		byte [] Sendbuf = new byte [128];
		int Sendlen = addData2Cmd(cmd, data, 19, Sendbuf);
		//发送
		byte [] Readbuf = new byte[2048];
		int iRet = sendOneToOne(Sendbuf, Sendlen, Readbuf,Common.CMD_MAX_TIME);
		if(iRet == 9){ //只收到发送成功数据
			if (Readbuf[0] == 0x55 && (Readbuf[6] == cmd[0]) && (Readbuf[7] == cmd[1])){ //命令发送成功
				//继续接收命令
				iRet = readData(Readbuf, maxtime + 1000);
				if (iRet > 0){
					if (Readbuf[0] == 0x55 && ((Readbuf[6] & 0xFF) == cmd[0] + 0x40) && (Readbuf[7] == cmd[1])){
						iRet = (Readbuf[4] * 0x100 + Readbuf[5]) - 3;//返回长度
						//拆开CAN包重组CAN数据
						iRet = 10;
						System.arraycopy(Readbuf, 8, recv, 0, iRet);
					}else iRet = 0;
				}else
					iRet = 0;
			}else
				iRet = 0;
		}else if(iRet > 9){ //一次性接收回来完了
			if(Readbuf[9] == 0x55 && ((Readbuf[15] & 0xFF) == cmd[0] + 0x40) && (Readbuf[16] == cmd[1])){
				iRet = (Readbuf[13] * 0x100 + Readbuf[14]) - 3;//返回长度
				//拆开CAN包重组CAN数据
				iRet = 10;
				System.arraycopy(Readbuf, 17, recv, 0, iRet);
			}else
				iRet = 0;
		}else
			iRet = 0;
		//记录接收的数据
		if(mLog != null && iRet > 0){
			if(iRet > 30)
				mLog.printMessage(4,Commonfunc.bytesToHexString(recv, 0, 30));
			else
				mLog.printMessage(4,Commonfunc.bytesToHexString(recv, 0, iRet));
		}
		return iRet;
	}

	/**
	 * 扩展帧只读一帧数据
	 * @param mode 模式
	 * @param recv_id 接收ID
	 * @param recv 接收字节数组
	 * @param maxtime 超时时间
	 * @return 通讯结果
	 */
	public int canExtedOnlyReadOne(byte mode,byte [] recv_id, byte [] recv, int maxtime){
		byte [] readbuf = new byte[256];
		int i,iRet = 0;
		for(i = 0; i < Common.CMD_REQUEST; i ++){

			iRet = canExtedReadOne(mode,recv_id,readbuf,maxtime);
			if(iRet > 0) break;
			if(i==Common.CMD_REQUEST-1) return 5001;
			Commonfunc.sleep(Common.WAIT_TIME);
		}
		if(iRet > recv.length) iRet = recv.length - 1;//复制接收数据
		System.arraycopy(readbuf, 0, recv, 0, iRet);
		Commonfunc.sleep(Common.WAIT_TIME);
		return iRet > 0 ? 0 : 5002;
	}

	/**
	 * 扩展帧只读一帧数据
	 * @param mode
	 * @param recv_id 接收ID
	 * @param recv 接收字节数组
	 * @param maxtime 超时时间
	 * @return 通讯结果
	 */

	private int canExtedReadOne(byte mode,byte[] rece_id, byte [] recv,int maxtime){
		byte [] cmd = new byte[]{0x11,0x37};
		byte [] data = new byte[512];
		if(mLog != null)
			mLog.printMessage(3,Commonfunc.bytesToHexString(rece_id, 0, rece_id.length));
		data[0] = mode;
		data[1] = 0;
		data[2] = 0;
		//超时时间
		data[3] = (byte) ((maxtime / 0x100) & 0xFF);
		data[4] = (byte) (maxtime & 0xFF);
		if(rece_id.length <= 8){ //添加一帧数据,单帧
			for (int i = 0; i < rece_id.length; i ++){
				data[5 + i] = rece_id[i];
			}
		}
		byte [] Sendbuf = new byte [512];
		int Sendlen = addData2Cmd(cmd, data, 5 + rece_id.length, Sendbuf);
		byte [] Readbuf = new byte[512];
		int iRet = sendOneToOne(Sendbuf, Sendlen, Readbuf, Common.CMD_MAX_TIME);
		if(iRet == 9){ //只收到发送成功数据
			if (Readbuf[0] == 0x55 && (Readbuf[6] == cmd[0]) && (Readbuf[7] == cmd[1])){ //命令发送成功
				//继续接收命令
				iRet = readData(Readbuf, maxtime + 1000);
				if (iRet > 0){
					if (Readbuf[0] == 0x55 && ((Readbuf[6] & 0xFF) == cmd[0] + 0x40) && (Readbuf[7] == cmd[1])){
						iRet = (Readbuf[4] * 0x100 + Readbuf[5]) - 3;//返回长度
						//拆开CAN包重组CAN数据
						if (Readbuf[8] == 1){ //单帧
							iRet = 8 + 1 + 1;
							for(int i = 0;i < iRet; i ++)
								recv[i] = Readbuf[8 + i];
						}else if ((Readbuf[8]&0xFF) > 1){ //多帧
							iRet = (Readbuf[8]&0xFF) * 9 + 1;
							for(int i = 0; i < iRet; i ++){
								recv[i] = Readbuf[8 + i];
							}
						}

					}else iRet = 0;
				}else iRet = 0;
			}else iRet = 0;
		}else if(iRet > 9){ //一次性接收回来完了
			if(Readbuf[9] == 0x55 && ((Readbuf[15] & 0xFF) == cmd[0] + 0x40) && (Readbuf[16] == cmd[1])){
				iRet = (Readbuf[13] * 0x100 + Readbuf[14]) - 3;//返回长度
				if (Readbuf[17] == 1){ //单帧 //拆开CAN包重组CAN数据
					iRet = 8 + 1 + 1;
					for(int i = 0;i < iRet; i ++)
						recv[i] = Readbuf[17 + i];
				}else if ((Readbuf[17]&0xFF) > 1){ //多帧
					iRet = (Readbuf[17]&0xFF) * 9 + 1;
					for(int i = 0; i < iRet; i ++){
						recv[i] = Readbuf[17 + i];
					}
				}
			}else iRet = 0;
		}else iRet = 0;
		if(mLog != null && iRet > 0)//记录接收的数据
			mLog.printMessage(2,Commonfunc.bytesToHexString(recv, 0, iRet));
		return iRet;
	}
}
